Conversation
Summary of ChangesHello @marcusmotill, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Response from ADK Triaging Agent Hello @marcusmotill, thank you for creating this PR! Could you please associate a GitHub issue with this PR? If there is no existing issue, could you please create one? In addition, could you please provide a testing plan in the PR description? This information will help reviewers to review your PR more efficiently. Thanks! |
There was a problem hiding this comment.
Code Review
This pull request introduces a runtime module to abstract system primitives like time and UUID generation, which is a great step towards enabling deterministic execution for durable integrations. The changes in event.py and in_memory_session_service.py correctly adopt this new module. My review focuses on improving the maintainability and testability of the new runtime module by suggesting a way to centralize the default provider logic, which will simplify test setup and teardown.
|
Thank you for the PR! Could you use a different name than 'runtime'? runtime is too general and may be confused with something else. Or you don't need a wrapper for time and id provider and make them top level. |
Moves runtime, event, and session service changes to a separate branch. These changes support deterministic execution required for durable integrations.
8e7a7bc to
5abb519
Compare
|
/gemini summary |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
/gemini review |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
|
||
| def new_invocation_context_id() -> str: | ||
| return "e-" + str(uuid.uuid4()) | ||
| return "e-" + platform_uuid.new_uuid() |
There was a problem hiding this comment.
There are multiple uuid.uuid4() and time.time() call sites throughout the SDK that are not changed in this PR. Is that intentional?
There was a problem hiding this comment.
yes, the intention is to only change the things we need to limit the PR. While we could swap out all instances, we don't need to. Now the real question is, did I get all the ones we need? I am not positive but this batch is a good start for the most common paths I see.
open to taking more of a blanket approach and change more than we need, open to thoughts...
There was a problem hiding this comment.
Having two patterns side-by-side is a maintenance trap. A new contributor won't know which to use, and nobody will want to audit whether their code is "on the workflow path" before picking one.
A single rule is much easier to follow than "use them only if your code might run in a Temporal workflow." The cost of converting the remaining sites is low and it eliminates the ambiguity entirely.
Honestly it would be best to
- Convert all remaining call sites in this PR
- Add to create a linting rule to prevent drift (this can be a follow up)
There was a problem hiding this comment.
I don't disagree, will do a further audit of other locations and look into a linting rule 👍
There was a problem hiding this comment.
This should be resolved, suggestion on the mechanism for lint rule?
src/google/adk/events/event.py
Outdated
| @@ -18,6 +18,8 @@ | |||
| from typing import Optional | |||
| import uuid | |||
There was a problem hiding this comment.
Do we still need to import this?
|
@sasha-gitg contextvar and hygiene changes made, if you have preference on naming (platform) feel free to pick a one and I can reflect.. this is our second name iteration from runtime and have low energy on that decision 😄 |
|
|
||
| def new_invocation_context_id() -> str: | ||
| return "e-" + str(uuid.uuid4()) | ||
| return "e-" + platform_uuid.new_uuid() |
There was a problem hiding this comment.
Having two patterns side-by-side is a maintenance trap. A new contributor won't know which to use, and nobody will want to audit whether their code is "on the workflow path" before picking one.
A single rule is much easier to follow than "use them only if your code might run in a Temporal workflow." The cost of converting the remaining sites is low and it eliminates the ambiguity entirely.
Honestly it would be best to
- Convert all remaining call sites in this PR
- Add to create a linting rule to prevent drift (this can be a follow up)
| ), | ||
| citation_metadata=types.CitationMetadata(), | ||
| custom_metadata={'custom_key': 'custom_value'}, | ||
| timestamp=1700000000.123, |
There was a problem hiding this comment.
easiest solution to avoid nasty percision issues in other tests when saving a timestamp to the DB... basically our new global time (time.time) gave 1 more decimal of precision than datetime.now().timestamp() and this issue surfaced
Problem:
The current implementation of
SessionService,Event, and other core components relies directly ontime.time()anduuid.uuid4(). These standard library functions are non-deterministic, which prevents the ADK from being used in deterministic execution environments (like Temporal workflows). In such environments, logic that depends on time or random IDs must be replayable and consistent across executions.Solution:
Introduced
google.adk.platform.timeandgoogle.adk.platform.uuidmodules to abstract time and UUID generation.google.adk.platform.timewithget_time()andset_time_provider().google.adk.platform.uuidwithnew_uuid()andset_id_provider().Event,SessionService,InvocationContext, andSqliteSessionServiceto use these new platform abstractions instead oftimeanduuiddirectly.This allows runtimes to inject deterministic providers (e.g., Temporal's
workflow.now()and side-effect-safe UUIDs) when running in a deterministic context, while defaulting to standardtimeanduuidfor standard execution.Testing Plan
Unit Tests:
Added new unit tests for the platform modules:
get_time, provider overriding, and resetting.new_uuid, provider overriding, and resetting.Manual End-to-End (E2E) Tests:
Verified that the ADK continues to function correctly in standard (non-deterministic) environments, ensuring the default providers for time and UUIDs work as expected.
Checklist
Additional context
These changes are a prerequisite for the Temporal integration, allowing the ADK to run safely inside Temporal workflows without breaking determinism guarantees.